#include "stdafx.h"
#include "FCFile.h"
#include "GTKHost.h"
#include "GTKPaint.h"
#include "MainFrame.h"
#include <cairo.h>
#include <gtk/gtk.h>

FCNative *m_native = 0;
GTKHost *m_host = 0;
GTKPaint *m_paint = 0;
int m_mouseDownButton = 0;
GtkIMContext *m_context = 0;

gboolean deal_mouse_press(GtkWidget *widget, GdkEventButton *event, gpointer data)
{
	gtk_im_context_focus_in(m_context);
	FCPoint mp = {(int)event->x, (int)event->y};
	m_host->m_touchPoint = mp;
	FCTouchInfo touchInfo;
	touchInfo.m_clicks = 1;
	m_mouseDownButton = 0;
	switch(event->button){	
		case 1:
			touchInfo.m_firstTouch = true;
			touchInfo.m_firstPoint = mp;
			m_mouseDownButton = 1;
			break;
		case 3:
			touchInfo.m_secondTouch = true;
			touchInfo.m_secondPoint = mp;
			m_mouseDownButton = 2;
			break;
	}
 
	if(event->type == GDK_2BUTTON_PRESS){
		touchInfo.m_clicks = 2;
	}
	m_native->onMouseDown(touchInfo);
	return FALSE;
}
 
gboolean deal_mouse_release(GtkWidget *widget, GdkEventButton *event, gpointer data)
{
	FCPoint mp = {(int)event->x, (int)event->y};
	m_host->m_touchPoint = mp;
	FCTouchInfo touchInfo;
	touchInfo.m_clicks = 1;
	m_mouseDownButton = 0;
	switch(event->button){	
		case 1:
			touchInfo.m_firstTouch = true;
			touchInfo.m_firstPoint = mp;
			break;
		case 3:
			touchInfo.m_secondTouch = true;
			touchInfo.m_secondPoint = mp;
			break;
	}
 
	if(event->type == GDK_2BUTTON_PRESS){
		touchInfo.m_clicks = 2;
	}
	m_native->onMouseUp(touchInfo);
	return FALSE;
}
 
gboolean deal_motion_event(GtkWidget *widget, GdkEventMotion *event, gpointer data)
{
	FCPoint mp = {(int)event->x, (int)event->y};
	m_host->m_touchPoint = mp;
	FCTouchInfo touchInfo;
	if(m_mouseDownButton == 1){
		touchInfo.m_firstTouch = true;
		touchInfo.m_firstPoint = mp;
		touchInfo.m_clicks = 1;
	}else if(m_mouseDownButton == 2){
		touchInfo.m_secondTouch = true;
		touchInfo.m_secondPoint = mp;
		touchInfo.m_clicks = 1;
	}else{
		touchInfo.m_firstPoint = mp;
	}
	m_native->onMouseMove(touchInfo);
	return FALSE;
}

gboolean on_draw_event(GtkWidget* widget, cairo_t* cr) {
	if(m_paint){
		int li_width;
		int li_height;
		m_paint->m_cr = cr;
		li_width = gtk_widget_get_allocated_width(widget);
		li_height = gtk_widget_get_allocated_height(widget);
		FCSize clientSize = {(int)li_width, (int)li_height};
		m_host->m_clientSize = clientSize;
		FCSize newSize = {(int)li_width, (int)li_height};
		FCSize oldSize = m_native->getSize();
		if(oldSize.cx != newSize.cx || oldSize.cy != newSize.cy){
			m_native->setSize(newSize);
			m_native->update();
		}
		FCRect rect = {0, 0, newSize.cx, newSize.cy};
		m_host->onPaint(rect);
	}
	return TRUE;
}

gboolean deal_timer(GtkWidget* drawing_area) {
	if(m_host){
		m_host->onTimer();
	}
	return TRUE;
}

gboolean deal_scroll(GtkWidget *widget, GdkEventScroll *event, gpointer user_data) {
    FCPoint mp = {(int)event->x, (int)event->y};
	m_host->m_touchPoint = mp;
	FCTouchInfo touchInfo;
	touchInfo.m_firstPoint = mp;
	int delta = 0;
	if(event->direction == GDK_SCROLL_UP){
		delta = 1;
	}else if(event->direction == GDK_SCROLL_DOWN){
		delta = -1;
	}
	touchInfo.m_delta = delta;
	m_native->onMouseWheel(touchInfo);
	return FALSE;
}

static bool m_hasInput = false;

gboolean on_key_release_event(GtkWidget *widget, GdkEventKey *event, gpointer user_data) {  
	m_native->onKeyUp((int)event->keyval);
	m_hasInput = false;
    return FALSE;  
}  

gboolean key_callback(GtkWidget *widget,
                             GdkEventKey *event,
                             GtkIMContext *context) {
	m_hasInput = true;
	if (event->state & GDK_SHIFT_MASK) {  
		m_host->m_isShift = true;
	}else{
		m_host->m_isShift = false;
	}
	if (event->state & GDK_MOD1_MASK) {  
		m_host->m_isAlt = true;
	}else{
		m_host->m_isAlt = false;
	}
	if (event->state & GDK_CONTROL_MASK) {  
		m_host->m_isCtrl = true;
	}else{
		m_host->m_isCtrl = false;
	}
	int keyCode = (int)event->keyval;
	if(keyCode == 65288){
		keyCode = 8;
	}else if(keyCode == 65361){
		keyCode = 37;
	}else if(keyCode == 65362){
		keyCode = 38;
	}else if(keyCode == 65363){
		keyCode = 39;
	}else if(keyCode == 65364){
		keyCode = 40;
	}else if(keyCode == 65307){
		keyCode = 27;
	}else if(keyCode == 65293){
		keyCode = 13;
		m_native->onChar(keyCode);
	}else if(keyCode == 65289){
		keyCode = '\t';
		m_native->onChar(keyCode);
	}
	//shift
	else if(keyCode == 65505){

	}
	//alt
	else if(keyCode == 65513){

	}
	//ctrl
	else if(keyCode == 65507){

	}
	else{
		if(keyCode <= 256){
			m_native->onChar(keyCode);
		}
	}
	m_native->onKeyDown(keyCode);
	return gtk_im_context_filter_keypress(context, event);
}

gboolean gtk_entry_commit_cb (GtkIMContext *context, const guchar  *str, gpointer data)
{
	if(!m_hasInput){
		lstring inputText = (char*)str;
		if((int)inputText.length() > 0){
			FCView *focusedView = m_native->getFocusedView();
			if(focusedView){
				FCTextBox *textBox = dynamic_cast<FCTextBox*>(focusedView);
				if(textBox && !textBox->m_readOnly){
					String insertText = FCTran::stringToString(inputText);
					//iTextBox::onChar2(textBox, insertText);
				}
			}
		}
	}
	return FALSE;
}

int main( int argc, char *argv[])
{
	GtkWidget *window;
	gtk_init(&argc, &argv);
	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	GdkWindow *gdk_window = gtk_widget_get_window(GTK_WIDGET(window));
	m_context = gtk_im_multicontext_new();
	gtk_im_context_set_client_window(m_context, gdk_window);
	g_signal_connect(m_context, "commit", G_CALLBACK(gtk_entry_commit_cb), NULL);
	g_signal_connect(window, "key-press-event", G_CALLBACK(key_callback), m_context);
	gtk_window_set_title(GTK_WINDOW(window), "FaceCat-GTK+");
	gtk_widget_set_size_request(window, 800, 600);
	g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
	GtkWidget* drawingArea = gtk_drawing_area_new();
	g_timeout_add(10, (GSourceFunc)deal_timer, drawingArea);
	gtk_container_add(GTK_CONTAINER(window), drawingArea);
	g_signal_connect(drawingArea, "draw", G_CALLBACK(on_draw_event), NULL);
	g_signal_connect(drawingArea, "button-press-event", G_CALLBACK(deal_mouse_press), NULL);
	g_signal_connect(drawingArea, "motion-notify-event", G_CALLBACK(deal_motion_event), NULL);
	g_signal_connect(drawingArea, "button-release-event", G_CALLBACK(deal_mouse_release), NULL);
	g_signal_connect(drawingArea, "scroll-event", G_CALLBACK(deal_scroll), NULL);
	g_signal_connect(window, "key-release-event", G_CALLBACK(on_key_release_event), NULL);
	gtk_widget_add_events(drawingArea, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK);  
	m_native = new FCNative();
	m_paint = new GTKPaint();
	m_host = new GTKHost();
	m_native->setPaint(m_paint);
	m_host->setNative(m_native);
	m_native->setHost(m_host);
	m_host->m_drawingArea = drawingArea;
	m_paint->m_drawingArea = drawingArea;
	m_host->m_window = window;
	FCSize nativeSize = {700, 700};
	m_native->setSize(nativeSize);
	FCRect drawRect = {0, 0, nativeSize.cx, nativeSize.cy};
	m_host->m_clientSize = nativeSize;
	MainFrame *xml = new MainFrame();
	xml->setNative(m_native);
	xml->loadFile(L"mainframe.xml", 0);
	m_native->update();
	m_native->invalidate();
	gtk_widget_show_all(window);
	gtk_main();
	return 0;
}
